home *** CD-ROM | disk | FTP | other *** search
/ Sprite 1984 - 1993 / Sprite 1984 - 1993.iso / src / machserver / 1.098 / raid / devRaidLog.c < prev    next >
C/C++ Source or Header  |  1991-06-27  |  21KB  |  805 lines

  1. /* 
  2.  * devRaidLog.c --
  3.  *
  4.  *    Implements logging and recovery for raid devices.
  5.  *
  6.  * Copyright 1990 Regents of the University of California
  7.  * Permission to use, copy, modify, and distribute this
  8.  * software and its documentation for any purpose and without
  9.  * fee is hereby granted, provided that the above copyright
  10.  * notice appear in all copies.  The University of California
  11.  * makes no representations about the suitability of this
  12.  * software for any purpose.  It is provided "as is" without
  13.  * express or implied warranty.
  14.  */
  15.  
  16. #ifndef lint
  17. static char rcsid[] = "$Header: /sprite/src/kernel/raid/RCS/devRaidLog.c,v 1.10 91/06/27 12:10:29 eklee Exp $ SPRITE (Berkeley)";
  18. #endif /* not lint */
  19.  
  20. #include "sync.h"
  21. #include <sprite.h>
  22. #include <stdio.h>
  23. #include <stdlib.h>
  24. #include "devRaid.h"
  25. #include "devRaidDisk.h"
  26. #include "devRaidLog.h"
  27. #include "bitvec.h"
  28. #include "semaphore.h"
  29. #include "devRaidProto.h"
  30.  
  31. #define ConfigLoc(raidPtr) ((int)(raidPtr)->logDevOffset)
  32.  
  33. #define DiskLoc(raidPtr, col, row)    \
  34.     ((int)(raidPtr->logDevOffset+((raidPtr)->logHandlePtr->minTransferUnit*((col)*(raidPtr)->numRow+(row)+1))))
  35.  
  36. #define VecOffset(raidPtr, bit)    \
  37.     ((int)((((bit)/8)/(raidPtr)->log.logHandlePtr->minTransferUnit) \
  38.         *(raidPtr)->log.logHandlePtr->minTransferUnit))
  39.  
  40. #define VecLoc(raidPtr, bit)    \
  41.     ((int)((raidPtr)->log.logDevOffset + VecOffset(raidPtr, bit)))
  42.  
  43. #define VecNextLoc(raidPtr, bit)    \
  44.     ((int)((raidPtr)->log.logDevOffset +        \
  45.         (((bit)/8)/(raidPtr)->log.logHandlePtr->minTransferUnit + 1) \
  46.         *(raidPtr)->log.logHandlePtr->minTransferUnit))
  47.  
  48. /*
  49.  *----------------------------------------------------------------------
  50.  *
  51.  * Raid_InitLog --
  52.  *
  53.  * Results:
  54.  *
  55.  * Side effects:
  56.  *
  57.  *----------------------------------------------------------------------
  58.  */
  59. void
  60. Raid_InitLog(raidPtr)
  61.     Raid *raidPtr;
  62. {
  63.     Sync_SemInitDynamic(&raidPtr->log.mutex, "RAID log mutex");
  64.     raidPtr->log.enabled = 0;
  65.     raidPtr->log.busy = 0;
  66.     raidPtr->log.logHandlePtr = raidPtr->logHandlePtr;
  67.     raidPtr->log.logDevOffset =
  68.         DiskLoc(raidPtr, raidPtr->numCol, raidPtr->numRow);
  69.     raidPtr->log.diskLockVecNum = raidPtr->numStripe;
  70.     raidPtr->log.diskLockVecSize = VecSize(raidPtr->log.diskLockVecNum);
  71.     raidPtr->log.diskLockVec = MakeBitVec(8 *
  72.     (VecNextLoc(raidPtr,raidPtr->log.diskLockVecNum) - VecLoc(raidPtr, 0)));
  73.     raidPtr->log.minLogElem = raidPtr->log.diskLockVecNum;
  74.     raidPtr->log.maxLogElem = 0;
  75.     raidPtr->log.waitCurBufPtr = &raidPtr->log.flushed1;
  76.     raidPtr->log.waitNextBufPtr = &raidPtr->log.flushed2;
  77. #ifdef TESTING
  78.     Sync_CondInit(&raidPtr->log.flushed1);
  79.     Sync_CondInit(&raidPtr->log.flushed2);
  80. #endif TESTING
  81. }
  82.  
  83.  
  84. /*
  85.  *----------------------------------------------------------------------
  86.  *
  87.  * Raid_EnableLog --
  88.  *
  89.  * Results:
  90.  *
  91.  * Side effects:
  92.  *
  93.  *----------------------------------------------------------------------
  94.  */
  95. void
  96. Raid_EnableLog(raidPtr)
  97.     Raid *raidPtr;
  98. {
  99.     raidPtr->log.enabled = 1;
  100. }
  101.  
  102.  
  103. /*
  104.  *----------------------------------------------------------------------
  105.  *
  106.  * Raid_DisableLog --
  107.  *
  108.  * Results:
  109.  *
  110.  * Side effects:
  111.  *
  112.  *----------------------------------------------------------------------
  113.  */
  114. void
  115. Raid_DisableLog(raidPtr)
  116.     Raid *raidPtr;
  117. {
  118.     raidPtr->log.enabled = 0;
  119. }
  120.  
  121.  
  122. /*
  123.  *----------------------------------------------------------------------
  124.  *
  125.  * ProcessRaidLog --
  126.  *
  127.  * Results:
  128.  *
  129.  * Side effects:
  130.  *
  131.  *----------------------------------------------------------------------
  132.  */
  133. typedef struct {
  134.     Sync_Semaphore mutex;         /* Lock for synronizing updates of
  135.                                    * this structure with the call back
  136.                                    * function. */
  137.     Sync_Condition wait;          /* Condition valued used to wait for
  138.                                    * callback. */
  139.     int            numIO;         /* Is the operation finished or not? */
  140.     ReturnStatus   status;
  141. } InitControlBlock;
  142.  
  143. static void initDoneProc();
  144.  
  145. static ReturnStatus
  146. ProcessRaidLog(raidPtr)
  147.     Raid    *raidPtr;
  148. {
  149.     InitControlBlock controlBlock;
  150.     int         stripeID;
  151.     char    *statusCtrl = "sssssssssssssssssssssssssssssssssssssssssssss";
  152.  
  153. #ifdef TESTING
  154.     Sync_CondInit(&controlBlock.wait);
  155. #endif TESTING
  156.     controlBlock.status = SUCCESS;
  157.     controlBlock.numIO = 0;
  158.     controlBlock.numIO++;
  159.     FOR_ALL_VEC(raidPtr->log.diskLockVec, stripeID, raidPtr->numStripe) {
  160.     MASTER_LOCK(&controlBlock.mutex);
  161.     controlBlock.numIO++;
  162.     MASTER_UNLOCK(&controlBlock.mutex);
  163.     Raid_InitiateHardInit(raidPtr, stripeID, 1,
  164.         initDoneProc, (ClientData) &controlBlock, (int) &statusCtrl);
  165.     }
  166.     MASTER_LOCK(&controlBlock.mutex);
  167.     controlBlock.numIO--;
  168.     if (controlBlock.numIO == 0) {
  169.         MASTER_UNLOCK(&controlBlock.mutex);
  170.     } else {
  171.     Sync_MasterWait(&controlBlock.wait, &controlBlock.mutex, FALSE);
  172.         MASTER_UNLOCK(&controlBlock.mutex);
  173.     }
  174.     return controlBlock.status;
  175. }
  176.  
  177.  
  178. /*
  179.  *----------------------------------------------------------------------
  180.  *
  181.  * initDoneProc --
  182.  *
  183.  *    Callback procedure used by Raid_ApplyLog.
  184.  *      Is called after each parity reconstruction.
  185.  *
  186.  * Results:
  187.  *
  188.  * Side effects:
  189.  *
  190.  *----------------------------------------------------------------------
  191.  */
  192. static void
  193. initDoneProc(controlBlockPtr, status)
  194.     InitControlBlock    *controlBlockPtr;
  195.     ReturnStatus     status;
  196. {
  197.     if (status != SUCCESS) {
  198.     controlBlockPtr->status = status;
  199.     }
  200.     MASTER_LOCK(&controlBlockPtr->mutex); 
  201.     controlBlockPtr->numIO--; 
  202.     if (controlBlockPtr->numIO == 0) { 
  203.     Sync_MasterBroadcast(&controlBlockPtr->wait);
  204.         MASTER_UNLOCK(&controlBlockPtr->mutex); 
  205.     } else {
  206.         MASTER_UNLOCK(&controlBlockPtr->mutex); 
  207.     }
  208. }
  209.  
  210.  
  211. /*
  212.  *----------------------------------------------------------------------
  213.  *
  214.  * Raid_ApplyLog --
  215.  *
  216.  * Results:
  217.  *
  218.  * Side effects:
  219.  *
  220.  *----------------------------------------------------------------------
  221.  */
  222. ReturnStatus
  223. Raid_ApplyLog(raidPtr)
  224.     Raid *raidPtr;
  225. {
  226.     int                xferAmt;
  227.     DevBlockDeviceRequest    req;
  228.     ReturnStatus        status;
  229.  
  230.     req.operation    = FS_READ;
  231.     req.startAddress    = VecLoc(raidPtr, 0);
  232.     req.startAddrHigh    = 0;
  233.     req.bufferLen    =
  234.     VecNextLoc(raidPtr, raidPtr->log.diskLockVecNum) - VecLoc(raidPtr, 0);
  235.     req.buffer        = (char *) raidPtr->log.diskLockVec;
  236.     status = Dev_BlockDeviceIOSync(raidPtr->log.logHandlePtr, &req, &xferAmt);
  237.     if (status != SUCCESS) {
  238.     return status;
  239.     }
  240.     status = ProcessRaidLog(raidPtr);
  241.     if (status != SUCCESS) {
  242.     return status;
  243.     }
  244.     return SUCCESS;
  245. }
  246.  
  247.  
  248. /*
  249.  *----------------------------------------------------------------------
  250.  *
  251.  * Raid_SaveDiskState --
  252.  *    
  253.  * Results:
  254.  *
  255.  * Side effects:
  256.  *
  257.  *----------------------------------------------------------------------
  258.  */
  259. ReturnStatus
  260. Raid_SaveDiskState(raidPtr, col, row, type, unit, version, numValidSector)
  261.     Raid    *raidPtr;
  262.     int         col, row;
  263.     int         type, unit, version;
  264.     int         numValidSector;
  265.     
  266. {
  267.     DevBlockDeviceRequest req;
  268.     int xferAmt;
  269.     int *iBuf = (int *) malloc(raidPtr->logHandlePtr->minTransferUnit);
  270.     ReturnStatus    status;
  271.  
  272.     req.operation    = FS_WRITE;
  273.     req.startAddress    = DiskLoc(raidPtr, col, row);
  274.     req.startAddrHigh    = 0;
  275.     req.buffer        = (char *) iBuf;
  276.     req.bufferLen    = raidPtr->logHandlePtr->minTransferUnit;
  277.  
  278.     iBuf[0] = type;
  279.     iBuf[1] = unit;
  280.     iBuf[2] = version;
  281.     iBuf[3] = numValidSector;
  282.     status = Dev_BlockDeviceIOSync(raidPtr->logHandlePtr, &req, &xferAmt);
  283.     if (status != SUCCESS) {
  284.     return status;
  285.     }
  286.     free((char *) iBuf);
  287.     return SUCCESS;
  288. }
  289.  
  290.  
  291. /*
  292.  *----------------------------------------------------------------------
  293.  *
  294.  * Raid_SaveParam --
  295.  *    
  296.  * Results:
  297.  *
  298.  * Side effects:
  299.  *
  300.  *----------------------------------------------------------------------
  301.  */
  302. ReturnStatus
  303. Raid_SaveParam(raidPtr)
  304.     Raid    *raidPtr;
  305. {
  306.     DevBlockDeviceRequest req;
  307.     int xferAmt;
  308.     int *iBuf = (int *) malloc(raidPtr->logHandlePtr->minTransferUnit);
  309.     ReturnStatus    status;
  310.  
  311.     req.operation    = FS_WRITE;
  312.     req.startAddress    = ConfigLoc(raidPtr);
  313.     req.startAddrHigh    = 0;
  314.     req.bufferLen    = raidPtr->logHandlePtr->minTransferUnit;
  315.     req.buffer        = (char *) iBuf;
  316.     MASTER_LOCK(&raidPtr->mutex);
  317.     iBuf[0] = raidPtr->numRow;
  318.     iBuf[1] = raidPtr->numCol;
  319.     iBuf[2] = raidPtr->logBytesPerSector;
  320.     iBuf[3] = raidPtr->sectorsPerStripeUnit;
  321.     iBuf[4] = raidPtr->stripeUnitsPerDisk;
  322.     iBuf[5] = raidPtr->rowsPerGroup;
  323.     iBuf[6] = raidPtr->parityConfig;
  324.     MASTER_UNLOCK(&raidPtr->mutex);
  325.     status = Dev_BlockDeviceIOSync(raidPtr->logHandlePtr, &req, &xferAmt);
  326.     if (status != SUCCESS) {
  327.     return status;
  328.     }
  329.     free((char *) iBuf);
  330.     return SUCCESS;
  331. }
  332.  
  333.  
  334. /*
  335.  *----------------------------------------------------------------------
  336.  *
  337.  * Raid_SaveLog --
  338.  *    
  339.  * Results:
  340.  *
  341.  * Side effects:
  342.  *
  343.  *----------------------------------------------------------------------
  344.  */
  345. ReturnStatus
  346. Raid_SaveLog(raidPtr)
  347.     Raid    *raidPtr;
  348. {
  349.     DevBlockDeviceRequest    req;
  350.     int xferAmt;
  351.     ReturnStatus    status;
  352.  
  353.     req.operation       = FS_WRITE;
  354.     req.startAddress    = VecLoc(raidPtr, 0);
  355.     req.startAddrHigh   = 0;
  356.     req.bufferLen       =
  357.     VecNextLoc(raidPtr, raidPtr->log.diskLockVecNum) - VecLoc(raidPtr, 0);
  358.     req.buffer          = (char *) raidPtr->log.diskLockVec;
  359.  
  360.     status = Dev_BlockDeviceIOSync(raidPtr->logHandlePtr, &req, &xferAmt);
  361.     if (status != SUCCESS) {
  362.     return status;
  363.     }
  364.     return SUCCESS;
  365. }
  366.  
  367.  
  368. /*
  369.  *----------------------------------------------------------------------
  370.  *
  371.  * Raid_SaveState --
  372.  *    
  373.  *    Perform a consistent checkpoint of the raid state.
  374.  *      System must be queiesced.
  375.  *
  376.  * Results:
  377.  *
  378.  * Side effects:
  379.  *
  380.  *----------------------------------------------------------------------
  381.  */
  382. ReturnStatus
  383. Raid_SaveState(raidPtr)
  384.     Raid *raidPtr;
  385. {
  386.     int        col, row;
  387.     ReturnStatus status;
  388.     RaidDisk    *diskPtr;
  389.  
  390.     status = Raid_SaveParam(raidPtr);
  391.     if (status != SUCCESS) {
  392.     return status;
  393.     }
  394.     for ( row = 0; row < raidPtr->numRow; row++ ) {
  395.         for ( col = 0; col < raidPtr->numCol; col++ ) {
  396.         LockSema(&raidPtr->disk[col][row]->lock);
  397.         diskPtr = raidPtr->disk[col][row];
  398.         status = Raid_SaveDiskState(raidPtr, col, row, diskPtr->device.type,
  399.             diskPtr->device.unit, diskPtr->version,
  400.             diskPtr->numValidSector);
  401.         UnlockSema(&diskPtr->lock);
  402.         if (status != SUCCESS) {
  403.         return status;
  404.         }
  405.     }
  406.     }
  407. #ifndef TESTING
  408.     ClearBitVec(raidPtr->log.diskLockVec, raidPtr->log.diskLockVecNum);
  409. #endif TESTING
  410.     status = Raid_SaveLog(raidPtr);
  411.     if (status != SUCCESS) {
  412.     return status;
  413.     }
  414.     return status;
  415. }
  416.  
  417.  
  418. /*
  419.  *----------------------------------------------------------------------
  420.  *
  421.  * ComputeRaidParam --
  422.  *
  423.  *    Compute redundant but convenient information.
  424.  *
  425.  * Results:
  426.  *
  427.  * Side effects:
  428.  *
  429.  *----------------------------------------------------------------------
  430.  */
  431. static void
  432. ComputeRaidParam(raidPtr)
  433.     Raid    *raidPtr;
  434. {
  435.     /*
  436.      * Compute redundant but convenient information.
  437.      */
  438.     if (raidPtr->parityConfig == 'S') {
  439.     raidPtr->numDataCol = raidPtr->numCol;
  440.     } else {
  441.     raidPtr->numDataCol = raidPtr->numCol - 1;
  442.     }
  443.     switch (raidPtr->parityConfig) {
  444.     case 'X': case 'x': case 'f':
  445.     raidPtr->stripeUnitsPerDisk -=
  446.         raidPtr->stripeUnitsPerDisk % raidPtr->numCol;
  447.         raidPtr->dataStripeUnitsPerDisk =
  448.                 (raidPtr->stripeUnitsPerDisk * raidPtr->numDataCol) /
  449.         raidPtr->numCol;
  450.     break;
  451.     default:
  452.     raidPtr->dataStripeUnitsPerDisk = raidPtr->stripeUnitsPerDisk;
  453.     break;
  454.     }
  455.     raidPtr->groupsPerArray = raidPtr->numRow / raidPtr->rowsPerGroup;
  456.     raidPtr->numSector  = (unsigned) raidPtr->numRow * raidPtr->numDataCol
  457.         * raidPtr->sectorsPerStripeUnit * raidPtr->stripeUnitsPerDisk;
  458.     raidPtr->numStripe  = raidPtr->stripeUnitsPerDisk * raidPtr->numRow;
  459.     raidPtr->dataSectorsPerStripe =
  460.         raidPtr->numDataCol * raidPtr->sectorsPerStripeUnit;
  461.     raidPtr->sectorsPerDisk =
  462.         raidPtr->stripeUnitsPerDisk * raidPtr->sectorsPerStripeUnit;
  463.     raidPtr->bytesPerStripeUnit = raidPtr->sectorsPerStripeUnit <<
  464.         raidPtr->logBytesPerSector;
  465.     raidPtr->dataBytesPerStripe = raidPtr->dataSectorsPerStripe <<
  466.         raidPtr->logBytesPerSector;
  467. }
  468.  
  469.  
  470. /*
  471.  *----------------------------------------------------------------------
  472.  *
  473.  * Raid_Configure --
  474.  *
  475.  *    Configure raid device by reading the appropriate configuration file.
  476.  *
  477.  * Results:
  478.  *    None.
  479.  *
  480.  * Side effects:
  481.  *    Allocates and initializes data structures for raid device.
  482.  *
  483.  *----------------------------------------------------------------------
  484.  */
  485.  
  486. /* static */ ReturnStatus
  487. Raid_Configure(raidPtr, charBuf)
  488.     Raid    *raidPtr;
  489.     char    *charBuf;
  490. {
  491.     char    *charBufPtr;
  492.     int         col, row;
  493.     int         type, unit;
  494.     int         numScanned;
  495.     RaidDisk    *diskPtr;
  496.  
  497.     charBufPtr = charBuf;
  498.     /*
  499.      * Skip comments.
  500.      */
  501.     for (;;) {
  502.         if (!ScanLine(&charBufPtr, charBuf)) {
  503.         return FAILURE;
  504.         }
  505.         if (charBuf[0] != '#') {
  506.             break;
  507.         }
  508.     }
  509.  
  510.     /*
  511.      * Read dimensions of raid device.
  512.      */
  513.     numScanned = sscanf(charBuf, "%d %d %d %d %d %d %c %d %d %d",
  514.              &raidPtr->numRow,
  515.             &raidPtr->numCol,
  516.             &raidPtr->logBytesPerSector,
  517.             &raidPtr->sectorsPerStripeUnit,
  518.             &raidPtr->stripeUnitsPerDisk,
  519.             &raidPtr->rowsPerGroup,
  520.             &raidPtr->parityConfig,
  521.             &raidPtr->logDev.type,
  522.             &raidPtr->logDev.unit,
  523.             &raidPtr->logDevOffset);
  524.     if (numScanned != 10) {
  525.     return FAILURE;
  526.     }
  527.     ComputeRaidParam(raidPtr);
  528.  
  529.     /*
  530.      * Attach log device.
  531.      */
  532.     if (raidPtr->parityConfig != 'S') {
  533.     raidPtr->logHandlePtr = Dev_BlockDeviceAttach(&raidPtr->logDev);
  534.     if (raidPtr->logHandlePtr == (DevBlockDeviceHandle *) NIL) {
  535.         printf("RAID:ERR:Could not attach log device %d %d\n",
  536.             raidPtr->logDev.type, raidPtr->logDev.unit);
  537.         return FAILURE;
  538.     }
  539.     Raid_InitLog(raidPtr);
  540.     }
  541.  
  542.     /*
  543.      * Allocate RaidDisk structures; one for each logical disk.
  544.      */
  545.     raidPtr->disk = (RaidDisk ***)
  546.         malloc((unsigned)raidPtr->numCol * sizeof(RaidDisk **));
  547.     for ( col = 0; col < raidPtr->numCol; col++ ) {
  548.     raidPtr->disk[col] = (RaidDisk **)
  549.         malloc((unsigned)raidPtr->numRow * sizeof(RaidDisk *));
  550.     bzero((char*)raidPtr->disk[col],raidPtr->numRow*sizeof(RaidDisk *));
  551.     }
  552.  
  553.     /*
  554.      * Initialize RaidDisk structures.
  555.      */
  556.     for ( row = 0; row < raidPtr->numRow; row++ ) {
  557.         for ( col = 0; col < raidPtr->numCol; col++ ) {
  558.         if (!ScanWord(&charBufPtr, charBuf)) {
  559.         return FAILURE;
  560.         }
  561.         type = atoi(charBuf);
  562.         if (!ScanWord(&charBufPtr, charBuf)) {
  563.         return FAILURE;
  564.         }
  565.         unit = atoi(charBuf);
  566.         diskPtr = Raid_MakeDisk(col, row, type, unit, 1,
  567.             raidPtr->sectorsPerDisk);
  568.         if (diskPtr == (RaidDisk *) NIL) {
  569.         printf("Could not attach disk %d %d\n", type, unit);
  570.         return FAILURE;
  571.         }
  572.         raidPtr->disk[col][row] = diskPtr;
  573.     }
  574.     }
  575.  
  576.     raidPtr->state = RAID_VALID;
  577.     return SUCCESS;
  578. }
  579.  
  580.  
  581. /*
  582.  *----------------------------------------------------------------------
  583.  *
  584.  * Raid_RestoreState --
  585.  *
  586.  * Results:
  587.  *
  588.  * Side effects:
  589.  *
  590.  *----------------------------------------------------------------------
  591.  */
  592. ReturnStatus
  593. Raid_RestoreState(raidPtr)
  594.     Raid *raidPtr;
  595. {
  596.     DevBlockDeviceRequest    req;
  597.     int *iBuf = (int *) malloc(raidPtr->logHandlePtr->minTransferUnit);
  598.     int xferAmt;
  599.     ReturnStatus    status;
  600.     int    col, row;
  601.     RaidDisk        *diskPtr;
  602.  
  603.     req.operation    = FS_READ;
  604.     req.startAddress    = ConfigLoc(raidPtr);
  605.     req.startAddrHigh    = 0;
  606.     req.bufferLen    = raidPtr->logHandlePtr->minTransferUnit;
  607.     req.buffer        = (char *) iBuf;
  608.     status = Dev_BlockDeviceIOSync(raidPtr->logHandlePtr, &req, &xferAmt);
  609.     if (status != SUCCESS) {
  610.     return FAILURE;
  611.     }
  612.     raidPtr->numRow            = iBuf[0];
  613.     raidPtr->numCol            = iBuf[1];
  614.     raidPtr->logBytesPerSector        = iBuf[2];
  615.     raidPtr->sectorsPerStripeUnit    = iBuf[3];
  616.     raidPtr->stripeUnitsPerDisk        = iBuf[4];
  617.     raidPtr->rowsPerGroup        = iBuf[5];
  618.     raidPtr->parityConfig        = iBuf[6];
  619.     ComputeRaidParam(raidPtr);
  620.  
  621.     /*
  622.      * Allocate RaidDisk structures; one for each logical disk.
  623.      */
  624.     raidPtr->disk = (RaidDisk ***)
  625.         malloc((unsigned)raidPtr->numCol * sizeof(RaidDisk **));
  626.     for ( col = 0; col < raidPtr->numCol; col++ ) {
  627.     raidPtr->disk[col] = (RaidDisk **)
  628.         malloc((unsigned)raidPtr->numRow * sizeof(RaidDisk *));
  629.     bzero((char*)raidPtr->disk[col],raidPtr->numRow*sizeof(RaidDisk *));
  630.     }
  631.  
  632.     /*
  633.      * Initialize RaidDisk structures.
  634.      */
  635.     req.operation    = FS_READ;
  636.     req.startAddrHigh    = 0;
  637.     req.buffer        = (char *) iBuf;
  638.     req.bufferLen    = raidPtr->logHandlePtr->minTransferUnit;
  639.     for ( row = 0; row < raidPtr->numRow; row++ ) {
  640.         for ( col = 0; col < raidPtr->numCol; col++ ) {
  641.     req.startAddress = DiskLoc(raidPtr, col, row);
  642.     status = Dev_BlockDeviceIOSync(raidPtr->logHandlePtr, &req, &xferAmt);
  643.     if (status != SUCCESS) {
  644.         return FAILURE;
  645.     }
  646.     diskPtr = Raid_MakeDisk(col,row, iBuf[0], iBuf[1], iBuf[2], iBuf[3]);
  647.     if (diskPtr == (RaidDisk *) NIL) {
  648.         return FAILURE;
  649.     }
  650.     raidPtr->disk[col][row] = diskPtr;
  651.     }
  652.     }
  653.  
  654.     Raid_InitLog(raidPtr);
  655.     if (Raid_ApplyLog(raidPtr) != SUCCESS) {
  656.     return FAILURE;
  657.     }
  658.     raidPtr->state = RAID_VALID;
  659.     return SUCCESS;
  660. }
  661.  
  662.  
  663. /*
  664.  *----------------------------------------------------------------------
  665.  *
  666.  * Raid_MasterFlushLog --
  667.  *
  668.  *    Flush log to disk.
  669.  *
  670.  * Results:
  671.  *
  672.  * Side effects:
  673.  *
  674.  *----------------------------------------------------------------------
  675.  */
  676.  
  677. void
  678. Raid_MasterFlushLog(raidPtr)
  679.     Raid *raidPtr;
  680. {
  681.     if (raidPtr->log.busy) {
  682.     Sync_MasterWait(raidPtr->log.waitNextBufPtr, &raidPtr->log.mutex,FALSE);
  683.     return;
  684.     }
  685.     raidPtr->log.busy = 1;
  686.     
  687.     do {
  688.     DevBlockDeviceRequest    req;
  689.     Sync_Condition        *flushedPtr;
  690.     int xferAmt;
  691.  
  692.     req.operation       = FS_WRITE;
  693.     req.startAddress    =
  694.          VecLoc(raidPtr, raidPtr->log.minLogElem);
  695.     req.startAddrHigh   = 0;
  696.     req.bufferLen       = VecNextLoc(raidPtr, raidPtr->log.maxLogElem) - 
  697.         VecLoc(raidPtr, raidPtr->log.minLogElem);
  698.     req.buffer          = (char *) raidPtr->log.diskLockVec +
  699.         VecOffset(raidPtr, raidPtr->log.minLogElem);
  700.  
  701.     flushedPtr = raidPtr->log.waitNextBufPtr;
  702.     raidPtr->log.waitNextBufPtr = raidPtr->log.waitCurBufPtr;
  703.     raidPtr->log.waitCurBufPtr = flushedPtr;
  704.     raidPtr->log.minLogElem = raidPtr->log.diskLockVecNum;
  705.     raidPtr->log.maxLogElem = 0;
  706.  
  707.     MASTER_UNLOCK(&raidPtr->log.mutex);
  708.     while(Dev_BlockDeviceIOSync(raidPtr->logHandlePtr, &req, &xferAmt) !=
  709.         SUCCESS) {
  710.         Time time;
  711.         printf("Error writing log\n");
  712.         time.seconds = 10;
  713.         time.microseconds = 0;
  714.         Sync_WaitTime(time);
  715.     }
  716.     MASTER_LOCK(&raidPtr->log.mutex);
  717.     Sync_MasterBroadcast(raidPtr->log.waitCurBufPtr);
  718.     } while (raidPtr->log.minLogElem != raidPtr->log.diskLockVecNum);
  719.     raidPtr->log.busy = 0;
  720. }
  721.  
  722.  
  723. /*
  724.  *----------------------------------------------------------------------
  725.  *
  726.  * Raid_LogStripe --
  727.  *
  728.  *    Make an entry in the specified log.
  729.  *
  730.  * Results:
  731.  *    None.
  732.  *
  733.  * Side effects:
  734.  *
  735.  *----------------------------------------------------------------------
  736.  */
  737. void
  738. Raid_CheckPoint(raidPtr)
  739.     Raid    *raidPtr;
  740. {
  741.     MASTER_LOCK(&raidPtr->log.mutex);
  742.     if (!raidPtr->log.enabled) {
  743.     MASTER_UNLOCK(&raidPtr->log.mutex);
  744.     return;
  745.     }
  746.     MASTER_UNLOCK(&raidPtr->log.mutex);
  747.     printf("RAID:MSG:Checkpointing RAID\n");
  748.     Raid_Lock(raidPtr);
  749. #ifndef TESTING
  750.     ClearBitVec(raidPtr->log.diskLockVec, raidPtr->log.diskLockVecNum);
  751. #endif TESTING
  752.     Raid_SaveLog(raidPtr);
  753.     Raid_Unlock(raidPtr);
  754.     printf("RAID:MSG:Checkpoint Complete\n");
  755. }
  756.  
  757. #ifdef TESTING
  758. #define NUM_LOG_STRIPE 2
  759. #else
  760. #define NUM_LOG_STRIPE 100
  761. #endif
  762.  
  763. void
  764. Raid_LogStripe(raidPtr, stripeID)
  765.     Raid *raidPtr;
  766.     int      stripeID;
  767. {
  768.     if (IsSet(raidPtr->log.diskLockVec, stripeID)) {
  769.     return;
  770.     }
  771.  
  772.     /*
  773.      * Occasionally checkpoint log.
  774.      */
  775.     MASTER_LOCK(&raidPtr->mutex);
  776.     raidPtr->numStripeLocked++;
  777.     if (raidPtr->numStripeLocked % NUM_LOG_STRIPE == 0) {
  778.     MASTER_UNLOCK(&raidPtr->mutex);
  779.     Proc_CallFunc((void (*)
  780.         _ARGS_((ClientData clientData, Proc_CallInfo *callInfoPtr)))
  781.         Raid_CheckPoint, (ClientData) raidPtr, 0);
  782.     } else {
  783.     MASTER_UNLOCK(&raidPtr->mutex);
  784.     }
  785.  
  786.     /*
  787.      * Write log.
  788.      */
  789.     MASTER_LOCK(&raidPtr->log.mutex);
  790.     if (!raidPtr->log.enabled) {
  791.     MASTER_UNLOCK(&raidPtr->log.mutex);
  792.     return;
  793.     }
  794.     SetBit(raidPtr->log.diskLockVec, stripeID);
  795.     if (stripeID < raidPtr->log.minLogElem) {
  796.     raidPtr->log.minLogElem = stripeID;
  797.     }
  798.     if (stripeID > raidPtr->log.maxLogElem) {
  799.     raidPtr->log.maxLogElem = stripeID;
  800.     }
  801.     Raid_MasterFlushLog(raidPtr);
  802.     MASTER_UNLOCK(&raidPtr->log.mutex);
  803. }
  804.  
  805.